package com.smartstate.iot.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.smartstate.iot.config.redis.RedisService;
import com.smartstate.iot.config.web.SpringUtils;
import com.smartstate.iot.entity.IotDataDistribution;
import com.smartstate.iot.entity.TopicConfig;
import com.smartstate.iot.entity.TopicLog;
import com.smartstate.iot.mapper.IotDataDistributionMapper;
import com.smartstate.iot.mapper.TopicLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 数据处理模块
 */
@Slf4j
public class PlcThreadService implements Runnable {

    @Resource
    RedisTemplate redisTemplate = RedisService.redis;

    String topic;
    String msg;

    public PlcThreadService(String topic, String msg) {
        this.topic = topic;
        this.msg = msg;
    }

    private String keys = "dataNumber";

    @Override
    public void run() {
        RedisService redisService = SpringUtils.getBean(RedisService.class);
        if (msg.length() > 0) {
            Map<String, Object> parse = (Map) JSON.parse(msg);
            String boxId = (String) parse.get("boxId");
            String ip = (String) parse.get("deviceIp");
            String deviceId = (String) parse.get("deviceId");
            String equipmentId = "";
            Object content = parse.get("content");
            JSONArray contentArray = JSON.parseArray(content.toString());
            boolean flag = false;
            HashMap<String, String> redisMap = new HashMap<>();
            HashMap<String, String> redisTypeMap = new HashMap<>();
            redisMap.put("ip", ip);
            redisMap.put("type", "正常");
            for (Object o : contentArray) {
                Map<String, Object> dataCollectionMap = JSON.parseObject(o.toString(), Map.class);
                boolean success = (boolean) dataCollectionMap.get("success");
                String attributeName = (String) dataCollectionMap.get("attributeName");
                int index = attributeName.indexOf(".");
                equipmentId = attributeName.substring(0, index);
                String mapKey = attributeName.substring(index + 1);
                if (success) {
                    Object value1 = dataCollectionMap.get("value");
                    System.out.println(value1);
                    Integer valueInt = null;
                    Boolean valueBool = null;
                    BigDecimal value = null;
                    Object valueObj = dataCollectionMap.get("value");
                    if (valueObj instanceof BigDecimal) {
                        value = (BigDecimal) dataCollectionMap.get("value");
                        value = value.setScale(2, RoundingMode.HALF_UP);
                        redisMap.put(mapKey, value.toString());
                    } else if (valueObj instanceof Boolean) {
                        valueBool = (Boolean) valueObj;
                        redisMap.put(mapKey, valueBool.toString());
                    } else if (valueObj instanceof Integer) {
                        valueInt = (Integer) valueObj;
                        redisMap.put(mapKey, valueInt.toString());
                    }
                    //  储存数据(中台使用)
                    System.out.println(redisMap);
                } else {
                    flag = true;
                    redisTypeMap.put(mapKey,"0");
                }
            }
            redisService.setCacheMap(equipmentId, redisMap);
            redisService.setCacheMap(boxId + ":" + deviceId + ":" + equipmentId, redisMap);
            if (flag) {
                redisTypeMap.put("type", "异常");
                redisService.setCacheMap(equipmentId, redisTypeMap);
                redisService.setCacheMap(boxId + ":" + deviceId + ":" + equipmentId, redisTypeMap);
            }
            log.info("设备数据保存成功！");
        }
    }

    /**
     * 递归跟新redis中的数据
     *
     * @param key
     * @param value
     */
    private void handout(String key, String value) {
        IotDataDistributionMapper dataDistributionMapper = SpringUtils.getBean(IotDataDistributionMapper.class);
        List<IotDataDistribution> mappings = dataDistributionMapper.getMapping(key);
        if (mappings.size() != 0) {
            RedisService redisService = SpringUtils.getBean(RedisService.class);
            HashMap<String, String> map = new HashMap<>();
            for (IotDataDistribution mapping : mappings) {
                double weight = mapping.getWeight();
                String targetKey = mapping.getDistributionTarget();
                //  TODO  修改数据分发
                int indexOf = targetKey.indexOf(".");
                String mapKey = targetKey.substring(indexOf + 1);
                String newValue = String.valueOf(Double.parseDouble(value) * weight);
                map.put(mapKey, newValue);
//                int index = key.indexOf(".");
                String hashKey = targetKey.substring(0, indexOf);
                //  缓存不带盒子的
                redisService.setCacheMap(hashKey, map);
                //  缓存带盒子的
                String boxKey = "";
                ArrayList<String> keys = getKeys();
                for (String s : keys) {
                    if (s.endsWith(hashKey)) {
                        boxKey = s;
                        break;
                    }
                }
                redisService.setCacheMap(boxKey, map);
                handout(targetKey, newValue);
            }
        }
    }

    /**
     * 获取redis中所有的key
     *
     * @return
     */
    private ArrayList<String> getKeys() {
        TopicLogMapper topicLogMapper = SpringUtils.getBean(TopicLogMapper.class);
        //  获取所有盒子
        List<TopicLog> topicLogs = topicLogMapper.getAllBox();
//        log.info(topicLogs.toString());
        TreeSet<String> boxName = new TreeSet<>();
        for (TopicLog topicLog : topicLogs) {
            boxName.add(topicLog.getDeviceId());
        }
        //  获取所有的key
        ArrayList<String> keys = new ArrayList<>();
        for (String logSet : boxName) {
            Set<String> tempKeys = redisTemplate.keys(logSet + ":*");
            if (tempKeys != null) {
                keys.addAll(tempKeys);
            }
        }
        return keys;
    }
}
